#include"StringOfSTL.h"

void test_string1()
{
	// 测试默认构造与析构
	fym::string s1;
	fym::string s2("hello world!");
	
	// 测试c_str()
	cout << "s1:" << s1.c_str() << endl;
	cout << endl;
	cout << "s2:" << s2.c_str() << endl;
	cout << endl;

	// 测试size()与operator[]
	for (int i = 0; i < s2.size(); i++)
	{
		s2[i] = 'F';
	}
	cout << "s2:" << s2.c_str() << endl;
	cout << endl;

	// 测试迭代器fym::string::iterator，begin()与end()
	fym::string::iterator it = s2.begin();
	while (it != s2.end())
	{
		*it = 'F';
		cout << *it << " ";
		it++;
	}
	cout << "\n" << endl;

	// 测试范围for
	for (auto ch : s2)
	{
		cout << ch << " ";
	}
	cout << endl;
}

void test_string2()
{
	// 测试push_back与+=一个字符
	fym::string s1;
	s1.push_back('A');
	s1.push_back('B');
	s1.push_back('C');
	cout << "push_back后s1:" << s1.c_str() << "\n" << endl;
	s1 += 'D';
	cout << "+=后s1:" << (s1 += 'E').c_str() << "\n" << endl;
	s1 += 'F';
	cout << "+=后s1:" << s1.c_str() << "\n" << endl;

	// 测试append与+=字符串
	fym::string s2("hello word");
	cout << "s2:" << s2.c_str() << "\n" << endl;
	s2.append("!");
	cout << "append后s2:" << s2.c_str() << "\n" << endl;
	cout << "+=后s2:" << (s2 += "I love you.").c_str() << "\n" << endl;

	// 测试insert插入一个字符
	s2.insert(s2.size(), '1');
	cout << "insert后s2:" << s2.c_str() << "\n" << endl;
	cout << "insert后s2:" << (s2.insert(s2.size(), '2')).c_str() << "\n" << endl;
	s2.insert(s2.size(), '3');
	cout << "insert后s2:" << s2.c_str() << "\n" << endl;
	s2.insert(5, ' ');
	cout << "insert后s2:" << s2.c_str() << "\n" << endl;
	s2.insert(0, '?');
	cout << "insert后s2:" << s2.c_str() << "\n" << endl;

	// 测试insert插入字符串
	s2.insert(s2.size(), "abc");
	cout << "insert后s2:" << s2.c_str() << "\n" << endl;
	cout << "insert后s2:" << (s2.insert(s2.size(), "def")).c_str() << "\n" << endl;
	s2.insert(s2.size(), "ghi");
	cout << "insert后s2:" << s2.c_str() << "\n" << endl;
	s2.insert(7, " 我 是 空 格 ");
	cout << "insert后s2:" << s2.c_str() << "\n" << endl;
	s2.insert(0, "我是头插 ");
	cout << "insert后s2:" << s2.c_str() << "\n" << endl;

	// 测试erase——s2:我是头插 ?hello  我 是 空 格  word!I love you.123abcdefghi
	s2.erase(s2.size() - 3, 3);
	// s2:我是头插 ?hello  我 是 空 格  word!I love you.123abcdef
	cout << "erase后s2:" << s2.c_str() << "\n" << endl;
	// s2:我是头插 ?hello  我 是 空 格  word!I love you.
	cout << "erase后s2:" << s2.erase(s2.size() - 9).c_str() << "\n" << endl;
	// s2:hello  我 是 空 格  word!I love you.
	s2.erase(0, 14);
	cout << "erase后s2:" << s2.c_str() << "\n" << endl;
	// s2:hell
	s2.erase(4, 700);
	cout << "erase后s2:" << s2.c_str() << "\n" << endl;

	// 测试find一个字符和字符串---s2:hell
	cout << s2.find('e') << "\n" << endl;
	cout << s2.find("ll") << "\n" << endl;
}
void test_string3()
{
	// 测试substr
	fym::string s("test.cpp.zip");
	size_t pos = s.find('.');
	// 正常情况下，此处两次拷贝构造
	// 一是在substr中，函数传值返回时，拷贝一个临时对象返回
	// 二是suffix接收临时对象，触发拷贝构造
	// 故需要在string类中显示实现深拷贝的拷贝构造
	// 若不实现，编译器自动生成浅拷贝，suffix._str会与substr函数中的局部对象sub._str共用一段空间
	// 在优化力度较大的情况下，编译器可能直接越过sub构建suffix，导致侥幸正常运行程序
	fym::string suffix = s.substr(pos);
	cout << suffix.c_str() << "\n" << endl;

	// 测试赋值operator=
	cout << "s:" << s.c_str() << endl;
	s = suffix;
	cout << "s:" << s.c_str() << "\nsuffix:" << suffix.c_str() << "\n" << endl;
	s = s;
	cout << "s:" << s.c_str() << endl;
}
void test_string4()
{
	// 测试比较操作符
	fym::string s1("abc");
	fym::string s2("abd");
	fym::string s3("abc");
	cout << (s1 < s2) << " " << (s1 <= s3) << endl;// 1 1
	cout << (s1 > s2) << " " << (s1 >= s3) << endl;// 0 1
	cout << (s1 == s2) << " " << (s1 != s3) << endl;// 0 0
	// 比较操作符重载时实现的是两个string类形参，此处能直接传字符串是因为字符串可以通过默认构造隐式类型转换成string类
	cout << (s1 == "abc") << " " << (s2 != "abc") << endl;// 1 1
	// 注意，两个字符串比较时不会调用string类重载的比较操作符，操作符重载只为类服务
	cout << ("abe" == "abe") << endl;
	cout << "-------------------------------" << endl;
	// 测试流插入、流提取
	using fym::operator<<;
	using fym::operator>>;
	cout << "s1:" << s1 << " " << "s2:" << s2 << endl;
	cin >> s1;
	cout << "s1:" << s1 << endl;
}
int main()
{
	// test_string1();
	// test_string2();
	// test_string3();
	test_string4();
	return 0;
}